package com.hkts.reportform.purchase.service.imp;

import com.hkts.reportform.datastatics.dao.ReportDao;
import com.hkts.reportform.feign.FeignInterface;
import com.hkts.reportform.purchase.dao.PurchaseDao;
import com.hkts.reportform.purchase.service.PurchaseService;
import com.hkts.reportform.utils.CustomPage;
import com.hkts.reportform.utils.DateUtil;
import com.hkts.reportform.utils.ErpProperties;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import rx.Completable;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @ClassNamePurchaseServiceImp
 * @Description
 * @Author yck
 * @Date2020-11-17 10:38
 * @Version V1.0
 **/
@Service("purchaseServiceImp")
public class PurchaseServiceImp implements PurchaseService {
    @Autowired
    private PurchaseDao purchaseDaoImp;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    @Autowired
    private FeignInterface feignInterface;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ReportDao reportDaoImpl;

    @Override
    public CustomPage selectInventoryByNameOrCode(String nameOrCode,CustomPage page) {
        List<Map<String, Object>> maps = purchaseDaoImp.selectInventoryByNameOrCode(nameOrCode);
        page.setTotalRows(maps.size());
        int firstRow = page.getPageSize() * (page.getPageNumber() - 1) + 1;
        int lastRow = page.getPageSize() * page.getPageNumber();
        List<Map<String, Object>> maps1 = purchaseDaoImp.selectPageInventoryByNameOrCode(nameOrCode, firstRow + "", lastRow + "");
        page.setResultData(maps1);
        Map<String, Object> stringObjectMap = feignInterface.userInfo();
        Map<String, Object> result = (Map<String, Object>) stringObjectMap.get("result");
        List<String> id = redisTemplate.opsForList().range(ErpProperties.USER_SEARCH_INFO + result.get("id").toString(), 0, -1);
        if (id == null || id.size() == 0) {
            redisTemplate.opsForList().leftPush(ErpProperties.USER_SEARCH_INFO + result.get("id").toString(), nameOrCode);
        } else {
            redisTemplate.delete(ErpProperties.USER_SEARCH_INFO + result.get("id").toString());
            if (id.contains(nameOrCode)) {
                id.remove(nameOrCode);
            }
            Collections.reverse(id);
            if (id.size() >= 30) {
                id.remove(0);
            }
            id.add(nameOrCode);
            redisTemplate.opsForList().leftPushAll(ErpProperties.USER_SEARCH_INFO + result.get("id").toString(), id);
        }

        return page;
    }

    @Override
    public Map<String, Object> selectInventoryDetilByCode(String code) throws ExecutionException, InterruptedException {
        Map<String, Object> map = new HashMap<String, Object>();

        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            List<Map<String, Object>> maps = reportDaoImpl.selectInventoryByCInvCode(code);
            map.put("cInvCode", maps.get(0).get("cInvCode"));
            map.put("cInvName", maps.get(0).get("cInvName"));
            //cInvStd
            if(maps.get(0).get("cInvStd")==null){
                map.put("cInvStd", "");
            }else{
                map.put("cInvStd", maps.get(0).get("cInvStd"));
            }
        }, threadPoolExecutor);

        CompletableFuture<Void> voidCompletableFuture2 = CompletableFuture.runAsync(() -> {
            List<Map<String, Object>> maps = purchaseDaoImp.selectCurrentstockByCode(code);
            //iQuantity
            if (maps.size() > 0) {
                map.put("iQuantity", maps.get(0).get("iQuantity"));
            } else {
                map.put("iQuantity", 0);
            }
        }, threadPoolExecutor);
        CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {
            Map<String, Object> mapItem = new HashMap<String, Object>();
            Map<String, Object> mapValue = new HashMap<String, Object>();
            List<Map<String, Object>> maps = purchaseDaoImp.inventoryPriceByCode(code);
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            List<String> listDate = new ArrayList<String>();
            List<Float> listResult = new ArrayList<Float>();
            if (maps.size() > 0) {
                for (int i = 0; i < maps.size(); i++) {
                    listResult.add(Float.parseFloat(maps.get(i).get("iOriCost").toString()));
                    listDate.add(maps.get(i).get("dDate").toString());
                }
            } else {
                mapItem.put("chartData", 0);
            }
            mapValue.put("data", listResult);
            list.add(mapValue);
            try {
                mapItem.put("categories",DateUtil.dateListConvert(listDate) );
            } catch (ParseException e) {
                e.printStackTrace();
            }
            mapItem.put("series", list);
            map.put("chartData", mapItem);
        }, threadPoolExecutor);
        CompletableFuture.allOf(voidCompletableFuture, voidCompletableFuture1, voidCompletableFuture2).join();
        return map;
    }

    @Override
    public Map<String, Object> getOrderCountByDate(String dateType, String beginDate, String endDate) throws ParseException {
        List<String> dateArray = DateUtil.getDateArray(dateType, beginDate, endDate);
        List<Map<String, Object>> maps = purchaseDaoImp.getOrderCountByDate(dateArray.get(0), dateArray.get(dateArray.size() - 1));
        Map<String, Object> map = new HashMap<String, Object>();
        Map<String, Object> mapCount = new HashMap<String, Object>();
        List<String> list = new ArrayList<String>();
        List<Integer> listcCount = new ArrayList<Integer>();
        List<Integer> listResult = new ArrayList<Integer>();
        List<Map<String, Object>> lm = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < maps.size(); i++) {
            list.add(maps.get(i).get("date").toString());
            listcCount.add(Integer.parseInt(maps.get(i).get("count").toString()));
        }
        for (int i = 0; i < dateArray.size(); i++) {
            if (list.contains(dateArray.get(i))) {
                listResult.add(listcCount.get(list.indexOf(dateArray.get(i))));
            } else {
                listResult.add(0);
            }
        }
        map.put("categories", DateUtil.dateListConvert(dateArray));
        mapCount.put("data", listResult);
        lm.add(mapCount);
        map.put("series", lm);
        return map;
    }

    @Override
    public CustomPage orderExecution(String dateType, String beginDate, String endDate, CustomPage page) {
        DecimalFormat decimalFormat=new DecimalFormat(".00");
        List<String> dateArray = DateUtil.getDateArray(dateType, beginDate, endDate);
        List<Map<String, Object>> countOrderExecution = purchaseDaoImp.getCountOrderExecution(dateArray.get(0),
                dateArray.get(dateArray.size() - 1));
        int count = countOrderExecution.size();
        page.setTotalRows(count);
        int firstRow = page.getPageSize() * (page.getPageNumber() - 1) + 1;
        int lastRow = page.getPageSize() * page.getPageNumber();
        List<Map<String, Object>> pageOrderExecution = purchaseDaoImp.getPageOrderExecution(dateArray.get(0),
                dateArray.get(dateArray.size() - 1),
                firstRow + "",
                lastRow + "",page.getOrder());
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < pageOrderExecution.size(); i++) {
            Map<String, Object> map = new HashMap<String, Object>();
            float iQuantity = Float.parseFloat(pageOrderExecution.get(i).get("iQuantity").toString());
            float freceivedqty = Float.parseFloat(pageOrderExecution.get(i).get("freceivedqty").toString());
            float iReceivedQTY = Float.parseFloat(pageOrderExecution.get(i).get("iReceivedQTY").toString());
            map.put("iQuantity", iQuantity);
            float a = (freceivedqty + iReceivedQTY) / iQuantity*100;
            if(a>0){
                String format = decimalFormat.format(a);
                map.put("storageQuantityRate", format);
            }else{
                map.put("storageQuantityRate", "0.00");
            }
            map.put("storageQuantity", freceivedqty + iReceivedQTY);
            map.put("cPOID",pageOrderExecution.get(i).get("cPOID").toString());
            map.put("cAuditDate",pageOrderExecution.get(i).get("cAuditDate").toString());
            List<Map<String, Object>> poid = purchaseDaoImp.getCInvNameByPoid(pageOrderExecution.get(i).get("POID").toString());
            StringBuffer buffer = new StringBuffer();
            for (int j = 0; j < poid.size(); j++) {
                if (j == 0) {
                    buffer.append(poid.get(j).get("cInvName"));
                } else {
                    if (!buffer.toString().contains(poid.get(j).get("cInvName").toString())) {
                        buffer.append("," + poid.get(j).get("cInvName"));
                    }
                }
            }
            map.put("cInvNames", buffer.toString());
            list.add(map);
        }
        page.setResultData(list);
        return page;
    }
}
